package com.nti56.springboot.utils;



import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;


public class XStreamUtil {
    
	
	
	
	
    // 别名注解，这个别名就是XML文档中的元素名，Java的属性名不一定要与别名一致
    // 被转换的类 加别名，可以不用写 包名 
    //@XStreamAlias("name")
    
    // 属性注解，此price就是book的属性，在XML中显示为：<book price="108">
    //@XStreamAsAttribute()
    //@XStreamAlias("price")
    
    //  不输出的属性加注解
    //@XStreamOmitField 
    
    //@XStreamImplicit 隐式集合 
    //@XStreamImplicit(itemFieldName="part") 
    
    public static String toXml(Object obj) {
 //     XStream xstream=new XStream();
 //     XStream xstream=new XStream(new DomDriver()); //直接用jaxp dom来解释
    	// 解决双下划线问题
        XStream xstream=new XStream(new DomDriver(null,new XmlFriendlyReplacer("_-", "_"))); //指定编码解析器,直接用jaxp dom来解释     
        ////如果没有这句，xml中的根元素会是<包.类名>；或者说：注解根本就没生效，所以的元素名就是类的属性
        xstream.processAnnotations(obj.getClass()); //通过注解方式的，一定要有这句话
        return xstream.toXML(obj);
    }
    
    public static <T> T toBean(String xmlStr, Class<T> cls) {
        XStream xstream = new XStream(new DomDriver());
        XStream.setupDefaultSecurity(xstream); // to be removed after 1.5
        xstream.allowTypesByWildcard(new String[] {
            "com.nti56.springboot.**"
        });
        xstream.registerConverter(new DateConverter()); 
        xstream.processAnnotations(cls);
        @SuppressWarnings("unchecked")
        T t = (T) xstream.fromXML(xmlStr);
        return t;
    }
    
    /**
     * 写到xml文件中去
     * @Title: writeXMLFile 
     * @Description: TODO 
     * @param obj 对象
     * @param absPath 绝对路径
     * @param fileName  文件名
     * @return boolean
     */
   
    public static boolean toXMLFile(Object obj, String absPath, String fileName ){
        String strXml = toXml(obj);
        String filePath = absPath + fileName;
        File file = new File(filePath);
        if(!file.exists()){
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
                return false ;
            }
        }// end if 
        OutputStream ous = null ;
        try {
            ous = new FileOutputStream(file);
            ous.write(strXml.getBytes());
            ous.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }finally{
            if(ous != null )
                try {
                    ous.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return true ;
    }
    
    /**
     * 从xml文件读取报文
     * @Title: toBeanFromFile 
     * @Description: TODO 
     * @param absPath 绝对路径
     * @param fileName 文件名
     * @param cls
     * @throws Exception 
     * @return T
     */
    public static <T> T  toBeanFromFile(String absPath, String fileName,Class<T> cls) throws Exception{
        String filePath = absPath +fileName;
        InputStream ins = null ;
        try {
            ins = new FileInputStream(new File(filePath ));
        } catch (Exception e) {
            throw new Exception("读{"+ filePath +"}文件失败！", e);
        }
        XStream xstream=new XStream(new DomDriver("utf-8"));
        xstream.processAnnotations(cls);
        T obj =null;
        try {
            obj = (T)xstream.fromXML(ins);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            throw new Exception("解析{"+ filePath +"}文件失败！",e);
        }
        if(ins != null)
            ins.close();
        return obj;         
    } 
    
 
}
